package util

import (
	"blog2021/tools/logger"
	"bytes"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"html/template"
	"math/rand"
	"net/http"
	"os"
	"reflect"
	"strings"
	"time"
)

func MaxInt(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func MinInt(a, b int) int {
	if a > b {
		return b
	}
	return a
}

func If(cond bool, yes, no interface{}) interface{} {
	if cond {
		return yes
	}
	return no
}

func RandPick(total int, pick int) []int {
	if total < pick {
		return []int{}
	}

	start := time.Now().UnixNano()
	mp := map[int]int{}
	for {
		start = start + 1
		rand.Seed(start)
		n := rand.Intn(total)
		mp[n]++
		if len(mp) == pick {
			break
		}
	}

	result := make([]int, 0, len(mp))
	for k, _ := range mp {
		result = append(result, k)
	}

	return result
}

func IndexOf(arr []string, str string) int {
	for i, v := range arr {
		if v == str {
			return i
		}
	}
	return -1
}

type Pair struct {
	First  interface{}
	Second interface{}
}

type PairString struct {
	First  string
	Second string
}

func Sha1(str string) string {
	h := sha1.New()
	h.Write([]byte(str))
	return fmt.Sprintf("%x", h.Sum(nil))
}

func TemplateHtml(text string) template.HTML {
	return template.HTML(text)
}

func SplitSemicolon(text string) []string {
	result := []string{}
	arr := strings.Split(text, ";")
	for _, str := range arr {
		if len(str) > 0 {
			result = append(result, str)
		}
	}
	return result
}

func HttpGetJson(url string, resp interface{}) error {
	result, err := http.Get(url)
	if err == nil {
		defer result.Body.Close()
		return json.NewDecoder(result.Body).Decode(resp)
	}
	return err
}

func HttpGetJsonFromHeader(url string, header map[string]string, resp interface{}) error {
	req, _ := http.NewRequest("GET", url, nil)
	for k, v := range header {
		req.Header.Set(k, v)
	}
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	result, err := client.Do(req)
	if err != nil {
		logger.Error(err)
		return err
	}
	defer result.Body.Close()
	return json.NewDecoder(result.Body).Decode(resp)
}

func HttpPostJson(url string, data map[string]interface{}, resp interface{}) error {
	b, err := json.Marshal(data)
	if err != nil {
		return err
	}
	return HttpPostData(url, b, resp)
}

func HttpPostData(url string, b []byte, resp interface{}) error {
	reader := bytes.NewReader(b)
	request, err := http.NewRequest("POST", url, reader)
	if err != nil {
		return err
	}
	request.Header.Set("Accept", "application/json;charset=UTF-8")
	request.Header.Set("Content-Type", "application/json;charset=UTF-8")
	client := http.Client{}
	response, err := client.Do(request)
	if err != nil {
		return err
	}
	defer response.Body.Close()
	return json.NewDecoder(response.Body).Decode(resp)
}

func UniqueSliceString(s []string, caseSensitive bool) []string {
	result := make([]string, 0, len(s))
	mp := make(map[string]int)
	for _, v := range s {
		key := ""
		if caseSensitive {
			key = v
		} else {
			key = strings.ToLower(v)
		}
		if mp[key] == 0 {
			result = append(result, v)
		}
		mp[key] += 1
	}
	return result
}

func Uuidv4() (string, error) {
	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		fmt.Println("Error: ", err)
		return "", err
	}
	return fmt.Sprintf("%X%X%X%X%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]), nil
}

func SliceDelete(slice interface{}, index int) (interface{}, bool) {
	v := reflect.ValueOf(slice)
	if v.Kind() != reflect.Slice {
		return nil, false
	}
	if v.Len() == 0 || index < 0 || index > v.Len()-1 {
		return nil, false
	}
	return reflect.AppendSlice(v.Slice(0, index), v.Slice(index+1, v.Len())).Interface(), true
}

func PathExist(path string) bool {
	_, err := os.Stat(path)
	if err != nil {
		if os.IsExist(err) {
			return true
		}
		return false
	}
	return true
}
